home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / ODF Release 3 / ODFDev / Draw / Sources / DrawLink.cpp < prev    next >
Encoding:
Text File  |  1996-12-16  |  26.8 KB  |  844 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                DrawLink.cpp
  4. //    Release Version:    $ ODF 3 $
  5. //
  6. //    Author:                Henri Lamiraux
  7. //    Linking added by:    M.Boetcher
  8. //
  9. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  10. //
  11. //========================================================================================
  12.  
  13. #include "ODFDraw.hpp"
  14.  
  15. #ifndef DRAWLINK_H
  16. #include "DrawLink.h"
  17. #endif
  18.  
  19. #ifndef DRAWCONT_H
  20. #include "DrawCont.h"
  21. #endif
  22.  
  23. #ifndef DEFINES_K
  24. #include "Defines.k"
  25. #endif
  26.  
  27. #ifndef DRAWPART_H
  28. #include "DrawPart.h"
  29. #endif
  30.  
  31. #ifndef DRAWSEL_H
  32. #include "DrawSel.h"
  33. #endif
  34.  
  35. #ifndef BASESHP_H
  36. #include "BaseShp.h"
  37. #endif
  38.  
  39. #ifndef BOUNDSHP_H
  40. #include "BoundShp.h"
  41. #endif
  42.  
  43. #ifndef LINESHP_H
  44. #include "LineShp.h"
  45. #endif
  46.  
  47. #ifndef OVALSHP_H
  48. #include "OvalShp.h"
  49. #endif
  50.  
  51. #ifndef RECTSHP_H
  52. #include "RectShp.h"
  53. #endif
  54.  
  55. #ifndef RRECTSHP_H
  56. #include "RRectShp.h"
  57. #endif
  58.  
  59. #ifndef TEXTSHP_H
  60. #include "TextShp.h"
  61. #endif
  62.  
  63. #ifndef GROUPSHP_H
  64. #include "GroupShp.h"
  65. #endif
  66.  
  67. #ifndef DRAWPRXY_H
  68. #include "DrawPrxy.h"
  69. #endif
  70.  
  71. // ----- Framework Includes -----
  72.  
  73. #ifndef FWLNKITE_H
  74. #include "FWLnkIte.h"
  75. #endif
  76.  
  77. #ifndef FWSUUTIL_H
  78. #include "FWSUUtil.h"
  79. #endif
  80.  
  81. #ifndef FWPXYITE_H
  82. #include "FWPxyIte.h"
  83. #endif
  84.  
  85. #ifndef FWFRAME_H
  86. #include "FWFrame.h"
  87. #endif
  88.  
  89. #ifndef FWINTER_H
  90. #include "FWInter.h"
  91. #endif
  92.  
  93. #ifndef FWITERS_H
  94. #include "FWIters.h"
  95. #endif
  96.  
  97. #ifndef FWPRTITE_H
  98. #include "FWPrtIte.h"
  99. #endif
  100.  
  101. #ifndef FWPRESEN_H
  102. #include "FWPresen.h"
  103. #endif
  104.  
  105. #ifndef FWPXYFRM_H
  106. #include "FWPxyFrm.h"
  107. #endif
  108.  
  109. #ifndef FWUTIL_H
  110. #include "FWUtil.h"
  111. #endif
  112.  
  113. #ifndef FWCLNINF_H
  114. #include "FWClnInf.h"
  115. #endif
  116.  
  117. #ifndef FWBARRAY_H
  118. #include "FWBArray.h"
  119. #endif
  120.  
  121. #ifndef FWPRMISE_H
  122. #include "FWPrmise.h"
  123. #endif
  124.  
  125. // ----- Foundation Includes -----
  126.  
  127. #ifndef FWORDCOL_H
  128. #include "FWOrdCol.h"
  129. #endif
  130.  
  131. #ifndef FWMEMMGR_H
  132. #include "FWMemMgr.h"
  133. #endif
  134.  
  135. // for FW_SOMEnvironment
  136. #ifndef FWSOMENV_H
  137. #include "FWSOMEnv.h"
  138. #endif
  139.  
  140. // ----- OpenDoc Includes -----
  141.  
  142. #ifndef SOM_Module_OpenDoc_StdProps_defined
  143. #include <StdProps.xh>
  144. #endif
  145.  
  146. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  147. #include <StdTypes.xh>
  148. #endif
  149.  
  150. #ifndef SOM_ODStorageUnit_xh
  151. #include <StorageU.xh>
  152. #endif
  153.  
  154. #ifndef SOM_ODUndo_xh
  155. #include <Undo.xh>
  156. #endif
  157.  
  158. #ifndef SOM_ODSession_xh
  159. #include <ODSessn.xh>
  160. #endif
  161.  
  162. #ifndef SOM_ODLink_xh
  163. #include <Link.xh>
  164. #endif
  165.  
  166. #ifndef SOM_ODLinkSpec_xh
  167. #include <LinkSpec.xh>
  168. #endif
  169.  
  170. #ifndef SOM_ODLinkSource_xh
  171. #include <LinkSrc.xh>
  172. #endif
  173.  
  174. //========================================================================================
  175. // Segmentation
  176. //========================================================================================
  177.  
  178. #ifdef FW_BUILD_MAC
  179. #pragma segment odfdraw
  180. #endif
  181.  
  182. //========================================================================================
  183. //    Template Instantiations
  184. //========================================================================================
  185.  
  186. #include "FWTColl.tpp"
  187.  
  188. FW_DEFINE_AUTO_TEMPLATE(FW_TOrderedCollection, CDrawPublishLink)
  189. FW_DEFINE_AUTO_TEMPLATE(FW_TOrderedCollectionIterator, CDrawPublishLink)
  190. FW_DEFINE_AUTO_TEMPLATE(FW_TOrderedCollection, CDrawSubscribeLink)
  191. FW_DEFINE_AUTO_TEMPLATE(FW_TOrderedCollectionIterator, CDrawSubscribeLink)
  192.  
  193. #ifdef FW_USE_TEMPLATE_PRAGMAS
  194.     #pragma template_access public
  195.     #pragma template FW_TOrderedCollection<CDrawPublishLink>
  196.     #pragma template FW_TOrderedCollectionIterator<CDrawPublishLink>
  197.     #pragma template FW_TOrderedCollection<CDrawSubscribeLink>
  198.     #pragma template FW_TOrderedCollectionIterator<CDrawSubscribeLink>
  199. #else
  200.     template class FW_TOrderedCollection<CDrawPublishLink>;
  201.     template class FW_TOrderedCollectionIterator<CDrawPublishLink>;
  202.     template class FW_TOrderedCollection<CDrawSubscribeLink>;
  203.     template class FW_TOrderedCollectionIterator<CDrawSubscribeLink>;
  204. #endif
  205.  
  206. //========================================================================================
  207. //    class CDrawPublishLink
  208. //========================================================================================
  209.  
  210. //----------------------------------------------------------------------------------------
  211. //    CDrawPublishLink::CDrawPublishLink
  212. //----------------------------------------------------------------------------------------
  213.  
  214. CDrawPublishLink::CDrawPublishLink(Environment* ev, ODUpdateID updateID, 
  215.                                    FW_CPresentation* presentation, 
  216.                                    CDrawSelection* drawSelection,
  217.                                    FW_Boolean saveSelection) :
  218.     FW_CLinkSource(ev, updateID, presentation),
  219.     fDrawSelection(drawSelection),
  220.     fPublishedContent(NULL)
  221. {
  222.     CDrawContent* content = NULL;
  223.     if (saveSelection)        // Save the selected shapes so they can be published
  224.         content = fDrawSelection->GetDrawContent(ev);
  225.  
  226.     fPublishedContent = FW_NEW(CDrawLinkSourceContent, (ev, 
  227.                                             (CDrawPart*) presentation->GetPart(ev), 
  228.                                             content, this));
  229. }
  230.  
  231. //----------------------------------------------------------------------------------------
  232. //    CDrawPublishLink::~CDrawPublishLink
  233. //----------------------------------------------------------------------------------------
  234.  
  235. CDrawPublishLink::~CDrawPublishLink()
  236. {
  237.     // Have to delete any promise before deleting the content because the promise
  238.     // will attempt to access the content, which is shared, so have to preempt
  239.     // the inherited destructor
  240.     
  241.     if (fLinkPromise)
  242.     {
  243.         delete fLinkPromise;
  244.         fLinkPromise = NULL;
  245.     }
  246.     
  247.     delete fPublishedContent;
  248. }
  249.  
  250. //----------------------------------------------------------------------------------------
  251. //    CDrawPublishLink::LinkEstablished - Override
  252. //----------------------------------------------------------------------------------------
  253.  
  254. void CDrawPublishLink::LinkEstablished(Environment* ev)
  255. {
  256.     //---- Mark the collected shapes as published
  257.     CDrawContentShapeIterator ite(fPublishedContent);
  258.     for (CBaseShape* shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  259.     {
  260.         shape->SetPublishLink(ev, this);
  261.     }
  262. }
  263.  
  264. //----------------------------------------------------------------------------------------
  265. //    CDrawPublishLink::ExternalizeLinkContent - Override
  266. //----------------------------------------------------------------------------------------
  267.  
  268. void CDrawPublishLink::ExternalizeLinkContent(Environment* ev, ODStorageUnit* linkSU)
  269. {    
  270.     // -- Pick a frame, any frame --
  271.     FW_CPresentationFrameIterator piter(ev, fPresentation);
  272.     FW_CFrame* frame = piter.First(ev);
  273.     FW_ASSERT(frame);
  274.  
  275.     fDataInterchange->ExternalizeData(ev, fPublishedContent, frame, linkSU, FW_kLinkStorage, kODCloneToLink);
  276. }
  277.  
  278. //----------------------------------------------------------------------------------------
  279. //    CDrawPublishLink::HasEmbeddedFrame
  280. //----------------------------------------------------------------------------------------
  281. FW_Boolean CDrawPublishLink::HasEmbeddedFrame(Environment* ev, ODFrame* odFrame)
  282. {
  283.     // Is odFrame involved in this link source? (called by DoUpdateLinks)
  284.  
  285.     // --- Find out whether odFrame is involved in any link source ---
  286.     if (odFrame->GetLinkStatus(ev) == kODInLinkSource)
  287.     {
  288.         CDrawContentShapeIterator iter(fPublishedContent);
  289.         for (CBaseShape* shape = iter.First(); iter.IsNotComplete(); shape = iter.Next())
  290.         {
  291.             if ((shape->GetShapeType() == kProxyShape) && (((CProxyShape*)shape)->IsEmbeddedFrame(ev, odFrame)))
  292.                 return TRUE;
  293.         }
  294.     }
  295.  
  296.     return FALSE;
  297. }
  298.  
  299. //----------------------------------------------------------------------------------------
  300. //    CDrawPublishLink::RevealLinkSource
  301. //----------------------------------------------------------------------------------------
  302. void CDrawPublishLink::RevealLinkSource(Environment* ev, FW_CFrame* frame)
  303. {
  304. FW_UNUSED(frame);
  305.     fDrawSelection->SelectContent(ev, fPublishedContent);
  306. }
  307.  
  308. //----------------------------------------------------------------------------------------
  309. //    CDrawPublishLink::AddShape
  310. //----------------------------------------------------------------------------------------
  311. void CDrawPublishLink::AddShape(Environment* ev, CBaseShape* shape)
  312. {
  313.     shape->SetPublishLink(ev, this);
  314.     fPublishedContent->AddShape(ev, shape);
  315. }
  316.  
  317. //----------------------------------------------------------------------------------------
  318. //    CDrawPublishLink::RemoveShape
  319. //----------------------------------------------------------------------------------------
  320. void CDrawPublishLink::RemoveShape(Environment* ev, CBaseShape* shape)
  321. {
  322.     fPublishedContent->RemoveShape(ev, shape);
  323. }
  324.  
  325. //----------------------------------------------------------------------------------------
  326. //    CDrawPublishLink::DoExternalizeLink
  327. //----------------------------------------------------------------------------------------
  328.  
  329. void CDrawPublishLink::DoExternalizeLink(Environment* ev, 
  330.                                         ODStorageUnit* storageUnit,
  331.                                         FW_CCloneInfo* cloneInfo)
  332. {
  333. FW_UNUSED(cloneInfo);
  334.     //--- Write the number of shapes in the link ---
  335.     unsigned long shapeCount = fPublishedContent->CountShapes();
  336.     FW_ASSERT(shapeCount != 0);
  337.     FW_CByteArray byteArray(&shapeCount, sizeof(unsigned long));
  338.     storageUnit->SetValue(ev, byteArray);
  339.  
  340.     //--- Write the externalization index for each shape in the link ---
  341.     CDrawContentShapeIterator iter(fPublishedContent);
  342.     for (CBaseShape* shape = iter.First(); iter.IsNotComplete(); shape = iter.Next())
  343.     {
  344.         short extIndex = shape->GetExternalizationIndex();
  345.         byteArray.Set(&extIndex, sizeof(short));
  346.         storageUnit->SetValue(ev, byteArray);
  347.     }
  348. }
  349.  
  350. //----------------------------------------------------------------------------------------
  351. //    CDrawPublishLink::IsEmpty
  352. //----------------------------------------------------------------------------------------
  353. FW_Boolean CDrawPublishLink::IsEmpty()
  354. {
  355.     return (fPublishedContent->CountShapes() == 0);
  356. }
  357.  
  358. //----------------------------------------------------------------------------------------
  359. //    CDrawPublishLink::BreakLink
  360. //----------------------------------------------------------------------------------------
  361. void CDrawPublishLink::BreakLink(Environment* ev)
  362. {
  363.     FW_CLinkSource::BreakLink(ev);    // call inherited
  364.     
  365.     //---- Mark the collected shapes as not published
  366.     CDrawContentShapeIterator it(fPublishedContent);
  367.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  368.     {
  369.         shape->SetPublishLink(ev, NULL);
  370.     }
  371. }
  372.  
  373. //----------------------------------------------------------------------------------------
  374. //    CDrawPublishLink::RestoreLink
  375. //----------------------------------------------------------------------------------------
  376. void CDrawPublishLink::RestoreLink(Environment* ev, FW_CPart* part)
  377. {
  378.     FW_CLinkSource::RestoreLink(ev, part);    // call inherited
  379.     
  380.     //---- Mark the collected shapes as published
  381.     CDrawContentShapeIterator it(fPublishedContent);
  382.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  383.     {
  384.         shape->SetPublishLink(ev, this);
  385.     }
  386. }
  387.  
  388. //----------------------------------------------------------------------------------------
  389. //    CDrawPublishLink::IsOKtoUpdate
  390. //----------------------------------------------------------------------------------------
  391. FW_Boolean CDrawPublishLink::IsOKtoUpdate(Environment* ev, FW_Boolean forceUpdate)
  392. {
  393.     // Prevent updating of link when all its content has been removed
  394.     if (!forceUpdate && this->IsEmpty())
  395.         return FALSE;
  396.     
  397.     return FW_CLinkSource::IsOKtoUpdate(ev, forceUpdate);
  398. }
  399.  
  400. #pragma segment Main
  401. unsigned long CDrawPublishLink::Count()
  402. {
  403.     return fPublishedContent->CountShapes();
  404. }
  405.  
  406.  
  407.  
  408. //========================================================================================
  409. //    class CDrawSubscribeLink
  410. //========================================================================================
  411.  
  412. //----------------------------------------------------------------------------------------
  413. //    CDrawSubscribeLink::CDrawSubscribeLink
  414. //----------------------------------------------------------------------------------------
  415.  
  416. CDrawSubscribeLink::CDrawSubscribeLink(Environment* ev, ODLink* odLink, 
  417.                                         FW_CPresentation* presentation, 
  418.                                         CDrawSelection* drawSelection,
  419.                                         ODLinkInfo* linkInfo,
  420.                                         FW_Boolean createGroupShape) :
  421.     FW_CLinkDestination(ev, odLink, linkInfo, presentation),
  422.     fDrawPart((CDrawPart*) presentation->GetPart(ev)),
  423.     fDrawSelection(drawSelection),
  424.     fLinkedContent(NULL),
  425.     fGroupShape(NULL),
  426.     fFirstUpdate(true),
  427.     fFirstOffset(true),
  428.     fCalcGroupOffset(false)
  429. {
  430.     fUpdateOffset.Clear();
  431.  
  432.     //---- Create a new content object to hold the shapes in this link ----
  433.     fLinkedContent = FW_NEW(CDrawLinkContent, (ev, fDrawPart, this));
  434.  
  435.     if (createGroupShape)
  436.     {
  437.         //---- Create a new group shape to represent the linked shapes ---- 
  438.         fGroupShape = FW_NEW(CGroupShape, (fDrawPart));
  439.         fGroupShape->SetSubscribeLink(ev, this);
  440.     }
  441. }
  442.  
  443. //----------------------------------------------------------------------------------------
  444. //    CDrawSubscribeLink::~CDrawSubscribeLink
  445. //----------------------------------------------------------------------------------------
  446.  
  447. CDrawSubscribeLink::~CDrawSubscribeLink()
  448. {
  449.     FW_SOMEnvironment ev;
  450.     
  451.     delete fLinkedContent;
  452.     fGroupShape->Release();
  453. }
  454.  
  455. //---------------------------------------------------------------------------------------
  456. //    CDrawSubscribeLink::DoUpdateLink - Override
  457. //---------------------------------------------------------------------------------------
  458.  
  459. FW_Boolean CDrawSubscribeLink::DoUpdateLink(Environment* ev, ODStorageUnit* linkContentSU, ODPasteAsResult* embedAsInfo)
  460. {
  461.     // Find a frame to use for the scope frame
  462.     FW_CPresentationFrameIterator piter(ev, fPresentation);
  463.     FW_CFrame* frame = piter.First(ev);
  464.     FW_ASSERT(frame);
  465.  
  466.     if (!fFirstUpdate)
  467.         fLinkedContent->EmptyShapes(ev);    // remove linked shapes from our content
  468.  
  469.     // Read new shapes from the link SU into our content
  470.     FW_Boolean result = (fDataInterchange->InternalizeData(ev, fLinkedContent, frame, linkContentSU, 
  471.                                                 FW_kLinkStorage, kODCloneFromLink, embedAsInfo)
  472.                                                 != FW_kInternalizeFailed);
  473.     if (result)
  474.     {
  475.         // Merge newly-read link data with part data
  476.         this->UpdateLinkedContent(ev);
  477.  
  478.         // Force all frames to be redrawn
  479.         fPresentation->Invalidate(ev);
  480.     }
  481.     return result;
  482. }
  483.  
  484. //----------------------------------------------------------------------------------------
  485. //    CDrawSubscribeLink::UpdateLinkedContent
  486. //----------------------------------------------------------------------------------------
  487.  
  488. void CDrawSubscribeLink::UpdateLinkedContent(Environment* ev)
  489. {
  490.     // If we got this far, the link data was read successfully.
  491.  
  492.     if (fFirstUpdate)    // Add the group shape to the part
  493.     {
  494.         fDrawPart->AddShapeToPart(ev, fGroupShape);
  495.     }
  496.     else                // Delete obsolete data
  497.     {
  498.         fGroupShape->EmptyShapes();        // remove shapes and release them
  499.     }
  500.  
  501.     // Roll the new shapes into the group shape
  502.     fLinkedContent->GroupShapes(ev, fGroupShape);
  503.  
  504.     if (fCalcGroupOffset)
  505.     {
  506.         FW_CRect rect = fGroupShape->GetRectGeometry();
  507.         fGroupShape->OffsetShape(ev, fUpdateOffset.x - rect.left, fUpdateOffset.y - rect.top);
  508.     }
  509.     else if (!fFirstOffset && fUpdateOffset != FW_kZeroPoint)    // updating an existing link 
  510.     {
  511.         // move the linked shapes to their proper position
  512.         fGroupShape->OffsetShape(ev, fUpdateOffset.x, fUpdateOffset.y);
  513.     }
  514.  
  515.     // Redraw the new shapes
  516.     fLinkedContent->RedrawShapes(ev);
  517.  
  518.     fFirstUpdate = false;
  519.     fFirstOffset = false;
  520. }
  521.  
  522. //----------------------------------------------------------------------------------------
  523. //    CDrawSubscribeLink::BreakLink - Override
  524. //----------------------------------------------------------------------------------------
  525. void CDrawSubscribeLink::BreakLink(Environment* ev)
  526. {
  527.     FW_CLinkDestination::BreakLink(ev);
  528.  
  529.     this->InvalidateBorder(ev);            // force link borders to be redrawn
  530.     fGroupShape->SetSubscribeLink(ev, NULL);    // Change status of embedded frames
  531. }
  532.  
  533. //----------------------------------------------------------------------------------------
  534. //    CDrawSubscribeLink::LinkEstablished - Override
  535. //----------------------------------------------------------------------------------------
  536. void CDrawSubscribeLink::LinkEstablished(Environment* ev)
  537. {
  538.     // Mark the shapes as linked
  539.     fGroupShape->SetSubscribeLink(ev, this);
  540. }
  541.  
  542. //----------------------------------------------------------------------------------------
  543. //    CDrawSubscribeLink::SetGroupShape
  544. //----------------------------------------------------------------------------------------
  545. void CDrawSubscribeLink::SetGroupShape(Environment* ev, CGroupShape* groupShape)
  546. {
  547.     fGroupShape = groupShape;
  548.     fGroupShape->Acquire();
  549.     
  550.     groupShape->SetSubscribeLink(ev, this);
  551.  
  552.     // Add the grouped shapes to the linked content
  553.     CShapeCollectionIterator it(groupShape->GetShapeList());
  554.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  555.     {
  556.         fLinkedContent->AddShape(ev, shape);
  557.     }
  558.  
  559.     if (fLinkedContent->CountShapes() != 0)
  560.         fFirstUpdate = false;    // so that DoUpdateLink empties it before reading new shapes
  561.  
  562.     FW_CRect rect = groupShape->GetRectGeometry();
  563.     fUpdateOffset = rect.TopLeft();
  564.     fCalcGroupOffset = true;    /* force UpdateLinkedContent to calculate offset */
  565. }
  566.  
  567. //----------------------------------------------------------------------------------------
  568. //    CDrawSubscribeLink::AddShape
  569. //----------------------------------------------------------------------------------------
  570. void CDrawSubscribeLink::AddShape(Environment* ev, CBaseShape* shape)
  571. {
  572.     // Called by Link Manager when internalizing destination links
  573.     fLinkedContent->AddShape(ev, shape);
  574.     fGroupShape->AddShape(shape);
  575. }
  576.  
  577. //----------------------------------------------------------------------------------------
  578. //    CDrawSubscribeLink::SelectShapes
  579. //----------------------------------------------------------------------------------------
  580. void CDrawSubscribeLink::SelectShapes(Environment* ev)
  581. {
  582.     fDrawSelection->CloseSelection(ev);
  583.     fDrawSelection->AddToSelection(ev, fGroupShape, TRUE);
  584. }
  585.  
  586. //----------------------------------------------------------------------------------------
  587. //    CDrawSubscribeLink::DoExternalizeLink
  588. //----------------------------------------------------------------------------------------
  589.  
  590. void CDrawSubscribeLink::DoExternalizeLink(Environment* ev, 
  591.                                         ODStorageUnit* storageUnit,
  592.                                         FW_CCloneInfo* cloneInfo)
  593. {
  594. FW_UNUSED(cloneInfo);
  595.     //--- There is a single group shape in the link ---
  596.     FW_ASSERT(fGroupShape);
  597.     unsigned long shapeCount = 1;
  598.     FW_CByteArray byteArray(&shapeCount, sizeof(unsigned long));
  599.     storageUnit->SetValue(ev, byteArray);
  600.  
  601.     //--- Write the export index for the group shape ---
  602.     short extIndex = fGroupShape->GetExternalizationIndex();
  603.     byteArray.Set(&extIndex, sizeof(short));
  604.     storageUnit->SetValue(ev, byteArray);
  605. }
  606.  
  607. //----------------------------------------------------------------------------------------
  608. //    CDrawSubscribeLink::AdjustUpdateOffset
  609. //----------------------------------------------------------------------------------------
  610. void CDrawSubscribeLink::AdjustUpdateOffset(Environment* ev, const FW_CPoint& delta)
  611. {
  612. FW_UNUSED(ev);
  613.     fUpdateOffset += delta;
  614. }
  615.  
  616. //----------------------------------------------------------------------------------------
  617. //    CDrawSubscribeLink::GetContainingFrame
  618. //----------------------------------------------------------------------------------------
  619. FW_CFrame* CDrawSubscribeLink::GetContainingFrame(Environment* ev, ODFrame* odEmbeddedFrame)
  620. {
  621.     // Return the containing frame if odEmbeddedFrame is involved in this link.
  622.     // Called by FW_CLinkManager::EditInLinkAttempted
  623.  
  624.     if (odEmbeddedFrame->GetLinkStatus(ev) == kODInLinkDestination)
  625.     {
  626.         // -- Find out whether odEmbeddedFrame is one of my proxy shapes --
  627.         CShapeCollectionIterator iter(fGroupShape->GetShapeList());
  628.         for (CBaseShape* shape = iter.First(); iter.IsNotComplete(); shape = iter.Next())
  629.         {
  630.             if ((shape->GetShapeType() == kProxyShape) && (((CProxyShape*)shape)->IsEmbeddedFrame(ev, odEmbeddedFrame)))
  631.             {
  632.                 FW_CAcquiredODFrame aqContainingODFrame =  odEmbeddedFrame->AcquireContainingFrame(ev);
  633.                 return FW_CEmbeddingFrame::ODtoFWEmbeddingFrame(ev, aqContainingODFrame);
  634.             }
  635.         }
  636.     }
  637.  
  638.     return NULL;
  639. }
  640.  
  641. //========================================================================================
  642. //    class CDrawLinkManager
  643. //========================================================================================
  644.  
  645. FW_DEFINE_AUTO(CDrawLinkManager)
  646.     
  647. //----------------------------------------------------------------------------------------
  648. //    CDrawLinkManager constructor
  649. //----------------------------------------------------------------------------------------
  650.  
  651. CDrawLinkManager::CDrawLinkManager(Environment* ev, CDrawPart* part):
  652.     FW_CLinkManagerImplementation(ev, part),
  653.     fDrawPart(part)
  654. {
  655. }
  656.  
  657. //----------------------------------------------------------------------------------------
  658. //    CDrawLinkManager destructor
  659. //----------------------------------------------------------------------------------------
  660.  
  661. CDrawLinkManager::~CDrawLinkManager()
  662. {
  663. }
  664.  
  665. //----------------------------------------------------------------------------------------
  666. //    CDrawLinkManager::NewLinkSource - Override
  667. //----------------------------------------------------------------------------------------
  668.  
  669. FW_CLinkSource* CDrawLinkManager::NewLinkSource(Environment* ev, ODUpdateID changeID, 
  670.                                                 FW_CPresentation* presentation)
  671. {
  672.     return new CDrawPublishLink(ev, changeID, 
  673.                                 presentation, fDrawPart->fDrawSelection, 
  674.                                 TRUE);    // saveSelection = TRUE
  675. }
  676.  
  677. //----------------------------------------------------------------------------------------
  678. //    CDrawLinkManager::NewLinkDestination - Override
  679. //----------------------------------------------------------------------------------------
  680.  
  681. FW_CLinkDestination* CDrawLinkManager::NewLinkDestination(Environment* ev, ODLink *odLink,
  682.                                                           ODLinkInfo* linkInfo,
  683.                                                           FW_CPresentation* presentation)
  684. {
  685.     return new CDrawSubscribeLink(ev, odLink, presentation, fDrawPart->fDrawSelection, linkInfo);
  686. }
  687.  
  688. //----------------------------------------------------------------------------------------
  689. //    CDrawLinkManager::DoChangeLinkStatus - Override
  690. //----------------------------------------------------------------------------------------
  691.  
  692. void CDrawLinkManager::DoChangeLinkStatus(Environment* ev, ODFrame* odFrame)
  693. {
  694.     // call ODFrame::ChangeLinkStatus on any embedded frames that are involved in a link
  695.     // when a link is created, broken, moved, etc.
  696.     // odFrame is the frame of this part whose link status has changed.
  697.     
  698.     FW_CEmbeddingFrame* frame = FW_CEmbeddingFrame::ODtoFWEmbeddingFrame(ev, odFrame);
  699.     if (frame)
  700.     {
  701.         ODLinkStatus linkStatus = odFrame->GetLinkStatus(ev);
  702.  
  703.         // Only need to propagate linkStatus to embedded frames that don't participate in
  704.         // any of this part's links; otherwise their local link status takes precedence.
  705.  
  706.         CDrawContentShapeIterator iter(fDrawPart->GetDrawContent());
  707.         for (CBaseShape* shape = iter.First(); iter.IsNotComplete(); shape = iter.Next())
  708.         {
  709.             if (shape->GetShapeType() == kProxyShape)
  710.             {
  711.                 CProxyShape* proxyShape = (CProxyShape*)shape;
  712.                 if (!proxyShape->IsPublished() && !proxyShape->IsSubscribed())
  713.                 {
  714.                     proxyShape->ChangeLinkStatus(ev, linkStatus);
  715.                 }
  716.             }
  717.         }
  718.     }
  719. }
  720.  
  721. //----------------------------------------------------------------------------------------
  722. //    CDrawLinkManager::UndoPasteAs
  723. //----------------------------------------------------------------------------------------
  724. void CDrawLinkManager::UndoPasteAs(Environment* ev, CDrawSubscribeLink* link)
  725. {
  726.     //--- Remove subscribed shapes from the document ---
  727.     fDrawPart->fDrawSelection->CloseSelection(ev);
  728.     fDrawPart->RemoveShapeFromPart(ev, link->fGroupShape);
  729. }
  730.  
  731. //----------------------------------------------------------------------------------------
  732. //    CDrawLinkManager::RedoPasteAs
  733. //----------------------------------------------------------------------------------------
  734. void CDrawLinkManager::RedoPasteAs(Environment* ev, CDrawSubscribeLink* link)
  735. {
  736.     link->fGroupShape->RestoreShape(ev);
  737. }
  738.  
  739. //----------------------------------------------------------------------------------------
  740. //    CDrawLinkManager::GetSUValue
  741. //----------------------------------------------------------------------------------------
  742.  
  743. ODULong CDrawLinkManager::GetSUValue(Environment* ev, ODStorageUnit* su, 
  744.                                      unsigned long size, void *buffer)
  745. {
  746.     // Convenience function; also makes code easier to read
  747.     FW_CByteArray ba;
  748.     ODULong bytesRead = su->GetValue(ev, size, ba);
  749.     ba.CopyBuffer(buffer, bytesRead);
  750.     
  751.     return bytesRead;
  752. }
  753.  
  754. //----------------------------------------------------------------------------------------
  755. //    CDrawLinkManager::DoInternalizeOneDestLink - Override
  756. //----------------------------------------------------------------------------------------
  757.  
  758. FW_CLinkDestination* CDrawLinkManager::DoInternalizeOneDestLink(Environment* ev, ODStorageUnit* storageUnit,
  759.                                                             ODLink* odLink, ODLinkInfo* linkInfo)
  760. {
  761.     //--- Create a subscriber object for this link ---
  762.     CDrawSubscribeLink* destLink = new CDrawSubscribeLink(ev, odLink, 
  763.                                                           fDrawPart->GetMainPresentation(), 
  764.                                                           fDrawPart->fDrawSelection, linkInfo,
  765.                                                           false);    // don't create group shape
  766.  
  767.     //--- Read the number of shapes in the link ---
  768.     unsigned long shapeCount;
  769.     GetSUValue(ev, storageUnit, sizeof(unsigned long), &shapeCount);
  770.     FW_ASSERT(shapeCount == 1);    // There should be a single group shape
  771.  
  772.     //--- Read each shape index and add the shape to the source link ---
  773.     short extIndex;
  774.     GetSUValue(ev, storageUnit, sizeof(short), &extIndex);
  775.     CBaseShape* shape = fDrawPart->FindShapeWithIndex(extIndex);
  776.     FW_ASSERT(shape);
  777.     if (shape && shape->GetShapeType() == kGroupShape)
  778.     {
  779.         destLink->SetGroupShape(ev, (CGroupShape*)shape);
  780.     }
  781.  
  782.     return destLink;
  783. }
  784.  
  785. //----------------------------------------------------------------------------------------
  786. //    CDrawLinkManager::DoInternalizeOneSourceLink - Override
  787. //----------------------------------------------------------------------------------------
  788.  
  789. FW_CLinkSource* CDrawLinkManager::DoInternalizeOneSourceLink(Environment* ev, 
  790.                                                               ODStorageUnit* storageUnit,
  791.                                                               ODUpdateID updateID)
  792. {
  793.     //--- Create a publish object for this source link ---
  794.     CDrawPublishLink* sourceLink = new CDrawPublishLink(ev, updateID, fDrawPart->GetMainPresentation(), fDrawPart->fDrawSelection, FALSE);
  795.  
  796.     //--- Read the number of shapes in the link ---
  797.     unsigned long shapeCount;
  798.     GetSUValue(ev, storageUnit, sizeof(unsigned long), &shapeCount);
  799.  
  800.     //--- Read each shape index and add the shape to the source link ---
  801.     unsigned long shapesInLink = 0;
  802.     short extIndex;
  803.     while (shapeCount > 0)
  804.     {
  805.         GetSUValue(ev, storageUnit, sizeof(short), &extIndex);
  806.         CBaseShape* shape = fDrawPart->FindShapeWithIndex(extIndex);
  807.         if (shape)
  808.         {
  809.             sourceLink->AddShape(ev, shape);
  810.             shapesInLink++;
  811.         }
  812.         shapeCount--;
  813.     }
  814.  
  815.     //--- If no linked shapes were found, discard the link ---
  816.     if (shapesInLink == 0)
  817.     {
  818.         delete sourceLink;
  819.         sourceLink = NULL;
  820.     }
  821.  
  822.     return sourceLink;
  823. }
  824.  
  825. //----------------------------------------------------------------------------------------
  826. //    CDrawLinkManager::GetSourceLinkFormat - Override
  827. //----------------------------------------------------------------------------------------
  828.  
  829. ODValueType CDrawLinkManager::GetSourceLinkFormat(Environment* ev)
  830. {    
  831. FW_UNUSED(ev);
  832.     return kPublishFormat;
  833. }
  834.  
  835. //----------------------------------------------------------------------------------------
  836. //    CDrawLinkManager::GetDestLinkFormat - Override
  837. //----------------------------------------------------------------------------------------
  838.  
  839. ODValueType CDrawLinkManager::GetDestLinkFormat(Environment* ev)
  840. {    
  841. FW_UNUSED(ev);
  842.     return kSubscribeFormat;
  843. }
  844.